package com.whitehatsec.sentineldataexchange;

import java.io.FileInputStream;
import java.io.IOException;
import java.util.Properties;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.CommandLineParser;
import org.apache.commons.cli.GnuParser;
import org.apache.commons.cli.HelpFormatter;
import org.apache.commons.cli.Option;
import org.apache.commons.cli.OptionBuilder;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException;

/**
 * This executable class parses command line arguments, loads the properties file,
 * logs in to Sentinel, and then calls a custom-built data exchanger to exchange data
 * between Sentinel and other entities.
 *
 * Developers wishing to use this class should create a class implementing
 * com.whitehatsec.sentineldataexchange.IDataExchanger which will actually operate
 * on the data returned from Sentinel. 
 *
 * @author August Detlefsen [augustd@codemagi.com]
 */
public class Main {

	private static Options options;
	private static CommandLineParser parser;
	private static CommandLine line;

	static {
		// create Options object
		options = new Options();

		// add properties option
		Option propertiesFile = OptionBuilder.withArgName("file").hasArg().withDescription("use given file for properties").create("properties");
		options.addOption(propertiesFile);

		// add site ID option
		Option siteID = OptionBuilder.withArgName("ID").hasArg().withDescription("retrieve vulnerabilities for site with ID").create("siteID");
		options.addOption(siteID);

		// add verifyHostnames option
		Option verifyHostnames = OptionBuilder.withArgName("boolean").hasArg().withDescription("verify hostnames? default: true").create("verifyHostnames");
		options.addOption(verifyHostnames);

		// create the parser
		parser = new GnuParser();
	}

	public static void main(String[] args) {

		try {
			// parse the command line arguments
			line = parser.parse(options, args);
		} catch (ParseException exp) {
			// oops, something went wrong
			System.err.println("Parsing failed. Reason: " + exp.getMessage());
			System.exit(1);
		}

		// has the properties file name argument been passed?
		String propertiesFilename = line.getOptionValue("properties", "runtime.properties");

		//do we want to verify hostnames?
		Boolean verifyHostnames = Boolean.valueOf(line.getOptionValue("verifyHostnames", "true"));
		if (!verifyHostnames) {
			System.out.println("WARNING! Hostname verification disabled. This should not be used in a production environment.");
			Utils.setVerifyHostnames(verifyHostnames);
		}

		// Read properties file.
		Properties properties = new CommentedProperties();

		try {
			properties.load(new FileInputStream(propertiesFilename));
			properties.setProperty("PROPERTIES_FILENAME", propertiesFilename);
		} catch (IOException e) {
			System.err.println("ERROR: " + propertiesFilename + " not found!");
			System.exit(1);
		}

		// has the siteID been passed?
		Integer siteID = null;
		if (line.hasOption("siteID")) {
			// initialise the member variable
			siteID = Integer.parseInt(line.getOptionValue("siteID"));
		}

		//login to the Sentinel System
		SentinelLogin login = null;
		try {
			login = new SentinelLogin(properties);

		} catch (Exception e) {
			System.err.println("Unable to login to Sentinel");
			e.printStackTrace(System.err);
			System.exit(1);

		}

		//Exchange data between Sentinel and ???
		try {
			IDataExchanger dataExchanger = (IDataExchanger)Class.forName(properties.getProperty("DATAEXCHANGER_CLASS")).newInstance();
			dataExchanger.setProperties(properties);
			dataExchanger.setSiteID(siteID);
			dataExchanger.setLogin(login);
			dataExchanger.exchangeData();
		} catch (Exception e) {
			System.err.println("Data Exchange failed");
			e.printStackTrace(System.err);
			System.exit(1);
		}

	}

	public static void usage() {
		// automatically generate the help statement
		HelpFormatter formatter = new HelpFormatter();
		formatter.printHelp("java com.whitehatsec.sentineldataexchange.Main", options);
	}
}
